<template>
    <div style="width: 100%;position: relative;">
        <flexBox style="width: 100%;margin-bottom: 5px;" gap="5px">
            <el-input @keydown="(e) => {
                if (e.code == 'Enter' || e.code == 'NumpadEnter') {
                    searchFormItem.confirmInput = searchFormItem.input
                }
            }" v-model="searchFormItem.input" size="small" style="width: 100%;" placeholder="搜索字段名称、值"
                class="input-with-select">
                <template #append>
                    <el-button title="搜索" @click="() => {
                        searchFormItem.confirmInput = searchFormItem.input
                    }" size="small" :icon="Search" />
                </template>
            </el-input>
            <el-button v-if="searchFormItem.confirmInput" title="重置" @click="() => {
                searchFormItem.confirmInput = ''
                searchFormItem.input = ''
            }" size="small" :icon="Refresh" />
        </flexBox>
        <div style="width: 100%;position: absolute;top: 27px;left: 0;height: calc(100% - 27px);overflow-y: auto;padding: 0 4px;box-sizing: border-box;">
            <div v-if="isSearching"
                style="width: 100%;backdrop-filter: blur(40px);font-size: 14px;position: sticky;top: 0;margin-bottom: 5px;border-top: 1px solid lightgray;font-size: 12px;">
                {{
                    `字段名称包含“${searchFormItem.confirmInput}”（${searchFormItem.search().titleInclude.length}个/${searchFormItem.search().all.length}个）`
                }}
            </div>
            <flexBox style="width: 100%;" gap="5px" alignItems="center" justifyContent="flex-start"
                flexDirection="column">
                <flexBox v-for="(item, index) in (isSearching ? getFormDisplaySearchTitle() : getFormDisplayAll())"
                    style="width: 100%;" alignItems="flex-start" gap="5px">
                    <flexBox v-for="(subItem, subIndex) in item" style="width: 100%;" alignItems="flex-start" gap="5px"
                        justifyContent="center">
                        <span
                            style="word-break: keep-all;display: inline-block;min-width: 120px;line-height: 22px;user-select: none;font-size: 14px;text-align: right;"
                            v-html="tool.getStringHighlightedHTML(subItem.title + '：', [searchFormItem.confirmInput], {
                                color: 'red'
                            })"></span>
                        <div v-if="!readMode" style="width: 100%;">
                            <el-select filterable size="small" :disabled="subItem.readOnly || disableAll"
                                v-if="Array.isArray(subItem.type)" v-model="value[subItem.field]" placeholder=""
                                @change="() => {
                                    try {
                                        if (subItem.changeForm) {
                                            form = subItem.changeForm(value, form)
                                        }
                                    } catch (error) {

                                    }
                                    try {
                                        if (subItem.changeValue) {
                                            value = subItem.changeValue(value, form)
                                        }
                                    } catch (error) {

                                    }

                                }" style="width: 100%">
                                <el-option v-for="selectOptionItem in subItem.type" :key="selectOptionItem.title"
                                    :label="selectOptionItem.title" :value="selectOptionItem.value" />
                            </el-select>
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'singleText'" v-model="value[subItem.field]"
                                style="width: 100%" placeholder="" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'password'" v-model="value[subItem.field]"
                                style="width: 100%" placeholder="" type="password" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'multipleText'" v-model="value[subItem.field]"
                                style="width: 100%;max-width: 100%;min-width: 100%;" :rows="4" type="textarea"
                                placeholder="" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'number'" v-model="value[subItem.field]" type="number"
                                style="width: 100%" placeholder="" />
                            <el-date-picker size="small" style="width: 100%;" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'date'" v-model="value[subItem.field]" type="date"
                                placeholder="选择日期" />
                            <el-date-picker size="small" style="width: 100%;" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'datetime'" v-model="value[subItem.field]" type="datetime"
                                placeholder="选择日期时间" />
                            <el-card style="box-shadow: 0;" v-else-if="subItem.type == 'image'" class="box-card"
                                :disabled="subItem.readOnly || disableAll">
                                <div style="width: 100%;height: auto;display: flex;align-items: center;">
                                    <el-image style="width: 100px; height: 100px;margin-right: 16px;"
                                        :src="value[subItem.field]" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
                                        :preview-src-list="[value[subItem.field]]" fit="cover" />
                                    <el-button @click="value[subItem.field] = ''"
                                        v-if="value[subItem.field]">清除图片</el-button>
                                    <el-button @click="async () => {
                                        value[subItem.field] = await tool.selectImageAndConvertToBase64()
                                    }">{{
                                        value[subItem.field] ? '切换' : '选择' }}图片</el-button>
                                    <el-button @click="async () => {
                                        let data = await tool.readClipboardImageAsBase64()
                                        if (data) value[subItem.field] = data
                                        else tool.toast.error('未从剪切板中识别到图片')
                                    }">读取剪切板中的图片</el-button>
                                </div>

                            </el-card>
                            <el-input size="small" :disabled="subItem.readOnly || disableAll" v-else
                                v-model="value[subItem.field]" style="width: 100%" placeholder="" />
                        </div>
                        <div v-if="readMode" style="width: 100%;font-size: 14px;padding:5px 0;">
                            <div v-if="subItem.type == 'date'" v-html="tool.getStringHighlightedHTML(tool.formatDate3(new Date(value[subItem.field]), true), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else-if="subItem.type == 'datetime'" v-html="tool.getStringHighlightedHTML(tool.formatDate3(new Date(value[subItem.field])), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else-if="Array.isArray(subItem.type)" v-html="tool.getStringHighlightedHTML((() => {
                                for (let i = 0; i < subItem.type.length; i++) {
                                    if (subItem.type[i].value === value[subItem.field]) {
                                        return subItem.type[i].title
                                    }
                                }
                                return ''
                            })(), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else style="word-break: break-all;" v-html="tool.getStringHighlightedHTML(`${value[subItem.field]}`, [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                        </div>
                    </flexBox>
                </flexBox>
            </flexBox>
            <div v-if="isSearching"
                style="width: 100%;backdrop-filter: blur(40px);font-size: 14px;position: sticky;top: 0;margin-bottom: 5px;border-top: 1px solid lightgray;font-size: 12px;margin-top: 5px;">
                {{
                    `字段值包含“${searchFormItem.confirmInput}”（${searchFormItem.search().valueInclude.length}个/${searchFormItem.search().all.length}个）`
                }}
            </div>
            <flexBox v-if="isSearching" style="width: 100%;margin-top: 5px;" gap="5px" alignItems="center"
                justifyContent="flex-start" flexDirection="column">
                <flexBox v-for="(item, index) in getFormDisplaySearchValue()" style="width: 100%;"
                    alignItems="flex-start" gap="5px">
                    <flexBox v-for="(subItem, subIndex) in item" style="width: 100%;" alignItems="flex-start" gap="5px"
                        justifyContent="center">
                        <span
                            style="word-break: keep-all;display: inline-block;min-width: 120px;line-height: 22px;user-select: none;font-size: 14px;text-align: right;"
                            v-html="tool.getStringHighlightedHTML(subItem.title + '：', [searchFormItem.confirmInput], {
                                color: 'red'
                            })"></span>
                        <div v-if="!readMode" style="width: 100%;">
                            <el-select @change="() => {
                                try {
                                    if (subItem.changeForm) {
                                        form = subItem.changeForm(value, form)
                                    }
                                } catch (error) {

                                }
                                try {
                                    if (subItem.changeValue) {
                                        value = subItem.changeValue(value, form)
                                    }
                                } catch (error) {

                                }

                            }" filterable size="small" :disabled="subItem.readOnly || disableAll"
                                v-if="Array.isArray(subItem.type)" v-model="value[subItem.field]" placeholder=""
                                style="width: 100%">
                                <el-option v-for="selectOptionItem in subItem.type" :key="selectOptionItem.value"
                                    :label="selectOptionItem.title" :value="selectOptionItem.value" />
                            </el-select>
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'password'" v-model="value[subItem.field]"
                                style="width: 100%" placeholder="" type="password" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'singleText'" v-model="value[subItem.field]"
                                style="width: 100%" placeholder="" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'multipleText'" v-model="value[subItem.field]"
                                style="width: 100%;max-width: 100%;min-width: 100%;" :rows="4" type="textarea"
                                placeholder="" />
                            <el-input size="small" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'number'" v-model="value[subItem.field]" type="number"
                                style="width: 100%" placeholder="" />
                            <el-date-picker size="small" style="width: 100%;" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'date'" v-model="value[subItem.field]" type="date"
                                placeholder="选择日期" />
                            <el-date-picker size="small" style="width: 100%;" :disabled="subItem.readOnly || disableAll"
                                v-else-if="subItem.type == 'datetime'" v-model="value[subItem.field]" type="datetime"
                                placeholder="选择日期时间" />
                            <el-card style="box-shadow: 0;" v-else-if="subItem.type == 'image'" class="box-card"
                                :disabled="subItem.readOnly || disableAll">
                                <div style="width: 100%;height: auto;display: flex;align-items: center;">
                                    <el-image style="width: 100px; height: 100px;margin-right: 16px;"
                                        :src="value[subItem.field]" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
                                        :preview-src-list="[value[subItem.field]]" fit="cover" />
                                    <el-button @click="value[subItem.field] = ''"
                                        v-if="value[subItem.field]">清除图片</el-button>
                                    <el-button @click="async () => {
                                        value[subItem.field] = await tool.selectImageAndConvertToBase64()
                                    }">{{
                                        value[subItem.field] ? '切换' : '选择' }}图片</el-button>
                                    <el-button @click="async () => {
                                        let data = await tool.readClipboardImageAsBase64()
                                        if (data) value[subItem.field] = data
                                        else tool.toast.error('未从剪切板中识别到图片')
                                    }">读取剪切板中的图片</el-button>
                                </div>

                            </el-card>
                            <el-input size="small" :disabled="subItem.readOnly || disableAll" v-else
                                v-model="value[subItem.field]" style="width: 100%" placeholder="" />
                        </div>
                        <div v-if="readMode" style="width: 100%;font-size: 14px;padding:5px 0;">
                            <div v-if="subItem.type == 'date'" v-html="tool.getStringHighlightedHTML(tool.formatDate3(new Date(value[subItem.field]), true), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else-if="subItem.type == 'datetime'" v-html="tool.getStringHighlightedHTML(tool.formatDate3(new Date(value[subItem.field])), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else-if="Array.isArray(subItem.type)" v-html="tool.getStringHighlightedHTML((() => {
                                for (let i = 0; i < subItem.type.length; i++) {
                                    if (subItem.type[i].value === value[subItem.field]) {
                                        return subItem.type[i].title
                                    }
                                }
                                return ''
                            })(), [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                            <div v-else style="word-break: break-all;" v-html="tool.getStringHighlightedHTML(`${value[subItem.field]}`, [searchFormItem.confirmInput], {
                                color: 'red'
                            })">

                            </div>
                        </div>
                    </flexBox>
                </flexBox>
            </flexBox>
        </div>
    </div>

</template>

<script setup>
import { ref, reactive, defineProps, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import flexBox from './flexBox.vue';
import tool from '../modules/tool';
import { Refresh, Search } from '@element-plus/icons-vue'

const props = defineProps({
    form: {
        type: Array,
        default: []
    },
    value: {
        type: Object,
        default: {}
    },
    disabled: {
        type: Boolean,
        default: false
    },
    readMode: {
        type: Boolean,
        default: false
    },
    builders: {
        type: Object,
        default: {}
    }
})

const disableAll = computed(() => { return props.disabled })

const value = ref(props.value)

const emit = defineEmits(['change'])

watch(() => props.value, () => {
    value.value = tool.deepCopyObject(props.value)
}, {
    deep: true
})

watch(() => value, () => {
    if (props.builders) for (let i = 0; i < Object.keys(props.builders).length; i++) {
        value.value[Object.keys(props.builders)[i]] = tool.autoGenValue(props.builders[Object.keys(props.builders)[i]], value.value)
    }
    emit('change', value.value, props.form)
}, {
    deep: true
})

const searchFormItem = reactive({
    input: '',
    search() {
        let re = {
            isSearch: this.confirmInput.length ? true : false,
            titleInclude: [],
            valueInclude: [],
            fieldInclude: [],
            all: []
        }
        for (let i = 0; i < props.form.length; i++) {
            re.all.push(props.form[i])
            let t = this.isThisItemSearched(props.form[i])
            if (t.indexOf(1) + 1) re.titleInclude.push(props.form[i])
            if (t.indexOf(2) + 1) re.valueInclude.push(props.form[i])
            if (t.indexOf(3) + 1) re.fieldInclude.push(props.form[i])
        }
        return re
    },
    isThisItemSearched(formItem) {
        let re = []
        if (formItem.title.indexOf(this.confirmInput) != -1) re.push(1)
        if (`${value.value[formItem.field] ? value.value[formItem.field] : ''}`.indexOf(this.confirmInput) != -1) re.push(2)
        if (formItem.field.indexOf(this.confirmInput) != -1) re.push(3)
        return re
    },
    confirmInput: ''
})

const getDisplayArr = (defaultArr = []) => {
    let re = [[]]
    for (let i = 0; i < defaultArr.length; i++) {
        if (i) {
            if (defaultArr[i].wholeLine) {
                re.push([
                    defaultArr[i]
                ])
            } else {
                if (re[re.length - 1].length == 2) {
                    re.push([
                        defaultArr[i]
                    ])
                } else {
                    if (re[re.length - 1][0].wholeLine) {
                        re.push([
                            defaultArr[i]
                        ])
                    } else {
                        re[re.length - 1].push(defaultArr[i])
                    }
                }
            }
        } else {
            re[0].push(defaultArr[i])
        }
    }
    return re
}

const getFormDisplaySearchTitle = () => {
    return getDisplayArr(searchFormItem.search().titleInclude)
}

const getFormDisplaySearchValue = () => {
    return getDisplayArr(searchFormItem.search().valueInclude)
}

const getFormDisplayAll = () => {
    return getDisplayArr(searchFormItem.search().all)
}

const isSearching = computed(() => {
    return searchFormItem.search().isSearch
})

onMounted(async () => {
    console.log(props.form)
})

</script>

<style scoped></style>